package com.myway.components.sms.mail;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.mail.BodyPart;
import javax.mail.Flags;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;

import com.myway.dto.sms.DTOAttachFile;
import com.myway.utils.ftp.FTPClientUtil;


/**
 * 类名称：JavaMailUtil <br/>
 * 类描述：邮件接收工具类 <br/>
 * 创建时间：2015年11月4日 上午10:11:45 <br/>
 * @author 张涛
 * @version V1.0
 */
public class MailParsingUtil {

	private static MimeMessage mimeMessage = null;
	private String saveAttachPath = ""; // 附件下载后的存放目录
	private String attachRelativePath = ""; // 附件下载后的存放目录
	private StringBuffer bodyText = new StringBuffer(); // 存放邮件内容的StringBuffer对象
	private String dateFormat = "yy-MM-dd HH:mm"; // 默认的日前显示格式
	private static final String regEx_script = "<script[^>]*?>[\\s\\S]*?<\\/script>"; // 定义script的正则表达式
	private static final String regEx_style = "<style[^>]*?>[\\s\\S]*?<\\/style>"; // 定义style的正则表达式
	private static final String regEx_html = "<[^>]+>"; // 定义HTML标签的正则表达式
	private static final String regEx_space = "\\s*|\t|\r|\n";//定义空格回车换行符

	public MailParsingUtil() {
	}

	@SuppressWarnings("static-access")
	public MailParsingUtil(MimeMessage mimeMessage) {
		this.mimeMessage = mimeMessage;
	}

	/**
	 * 名称：getFrom <br/>
	 * 描述：获取发件人from和姓名:personal <br/>
	 * @return
	 * @throws MessagingException
	 */
	public String getFrom() throws MessagingException {
		String fromAddr = "this email not found from!";
		InternetAddress address[] = (InternetAddress[]) mimeMessage.getFrom();
		String from = address[0].getAddress();
		String personal = address[0].getPersonal();
		if (personal != null || from != null) {
			fromAddr = personal + "<" + from + ">";
		}
		return fromAddr;
	}

	/**
	 * 　*　获得邮件的收件人，抄送，和密送的地址和姓名，根据所传递的参数的不同
	 * 　*　"to"----收件人　"cc"---抄送人地址　"bcc"---密送人地址 　
	 */
	public String getMailAddress(String type) throws Exception {
		String mailAddr = "";
		String addType = type.toUpperCase();

		InternetAddress[] address = null;
		if (addType.equals("TO") || addType.equals("CC")
				|| addType.equals("BCC")) {

			if (addType.equals("TO")) {
				address = (InternetAddress[]) mimeMessage
						.getRecipients(Message.RecipientType.TO);
			} else if (addType.equals("CC")) {
				address = (InternetAddress[]) mimeMessage
						.getRecipients(Message.RecipientType.CC);
			} else {
				address = (InternetAddress[]) mimeMessage
						.getRecipients(Message.RecipientType.BCC);
			}

			if (address != null) {
				for (int i = 0; i < address.length; i++) {
					String emailAddr = address[i].getAddress();
					if (emailAddr == null) {
						emailAddr = "";
					} else {
						emailAddr = MimeUtility.decodeText(emailAddr);
					}
					String personal = address[i].getPersonal();
					if (personal == null) {
						personal = "";
					} else {
						personal = MimeUtility.decodeText(personal);
					}
					String compositeto = personal + "<" + emailAddr + ">";
					mailAddr += "," + compositeto;
				}
				mailAddr = mailAddr.substring(1);
			}
		} else {
			throw new Exception("错误的电子邮件类型!");
		}
		return mailAddr;
	}

	/**
	 *　获得邮件主题 　
	 * @throws UnsupportedEncodingException 没有主题
	 * @throws MessagingException 信息有误
	 */
	public String getSubject() throws UnsupportedEncodingException, MessagingException {
		String decodeText = MimeUtility.decodeText(mimeMessage.getSubject());
		return decodeText;
	}

	/**
	 * 　*　获得邮件发送日期 　
	 */
	public String getSentDate() throws Exception {
		Date sentDate = mimeMessage.getSentDate();
		SimpleDateFormat format = new SimpleDateFormat(dateFormat);
		String strSentDate = format.format(sentDate);
		return strSentDate;
	}

	/**
	 * 　*　获得邮件正文内容 　
	 */
	public String getBodyText() {
		return bodyText.toString();
	}

	/**
	 * 　　*　解析邮件，把得到的邮件内容保存到一个StringBuffer对象中，解析邮件
	 * 　　*　主要是根据MimeType类型的不同执行不同的操作，一步一步的解析 　　
	 */

	public void getMailContent(Part part) throws Exception {
		String contentType = part.getContentType();
		int nameIndex = contentType.indexOf("name");
		boolean conName = false;
		if (nameIndex != -1) {
			conName = true;
		}
		if (part.isMimeType("text/html") && conName == false) {
			bodyText.append((String) part.getContent());
		}else if (part.isMimeType("multipart/*")) {
			Multipart multipart = (Multipart) part.getContent();
			int counts = multipart.getCount();
			for (int i = 0; i < counts; i++) {
				getMailContent(multipart.getBodyPart(i));
			}
		} else if (part.isMimeType("message/rfc822")) {
			getMailContent((Part) part.getContent());
		}
	}

	/**
	 * 　获得此邮件的Message-ID 　　
	 */
	public String getMessageId() throws MessagingException {
		String messageID = mimeMessage.getMessageID();
		return messageID;
	}
	
	/**
	 * 名称：getUid <br/>
	 * 描述：获取邮件的UID <br/>
	 * @return
	 */
	public String getUid(){
		return "";
	}

	/**
	 * 名称：isNew <br/>
	 * 描述：判断邮件是否已读 <br/>
	 * @return
	 * @throws MessagingException
	 */
	public boolean isNew() throws MessagingException {
		boolean isNew = false;
		Flags flags = ((Message) mimeMessage).getFlags();
		Flags.Flag[] flag = flags.getSystemFlags();
		for (int i = 0; i < flag.length; i++) {
			if (flag[i] == Flags.Flag.SEEN) {
				isNew = true;
			}
		}
		return isNew;
	}

	
	/**
	 * 判断此邮件是否包含附件
	 */
	public boolean isContainAttach(Part part) throws Exception {
		boolean attachFlag = false;
		if (part.isMimeType("multipart/*")) {
			Multipart mp = (Multipart) part.getContent();
			for (int i = 0; i < mp.getCount(); i++) {
				BodyPart mPart = mp.getBodyPart(i);
				String disposition = mPart.getDisposition();
				if ((disposition != null)
						&& ((disposition.equals(Part.ATTACHMENT)) || (disposition
								.equals(Part.INLINE))))
					attachFlag = true;
				else if (mPart.isMimeType("multipart/*")) {
					attachFlag = isContainAttach((Part) mPart);
				} else {
					String conType = mPart.getContentType();

					if (conType.toLowerCase().indexOf("application") != -1)
						attachFlag = true;
					if (conType.toLowerCase().indexOf("name") != -1)
						attachFlag = true;
				}
			}
		} else if (part.isMimeType("message/rfc822")) {
			attachFlag = isContainAttach((Part) part.getContent());
		}
		return attachFlag;
	}

	/**
	 * 　*　保存附件 　
	 */
	public void saveAttachMent(Part part,String messageId,Map<String,List<DTOAttachFile>> attachFileMap,String uid) throws Exception {
		String fileName = "";
		if (part.isMimeType("multipart/*")) {
			Multipart mp = (Multipart) part.getContent();
			for (int i = 0; i < mp.getCount(); i++) {
				BodyPart mPart = mp.getBodyPart(i);
				String disposition = mPart.getDisposition();
				if ((disposition != null)
						&& ((disposition.equals(Part.ATTACHMENT)) || (disposition
								.equals(Part.INLINE)))) {
					fileName = mPart.getFileName();
					if (null != fileName) {
						fileName = MimeUtility.decodeText(fileName);
					}
					List<DTOAttachFile> list = attachFileMap.get(messageId);
					DTOAttachFile  dTOAttachFile = new DTOAttachFile();
					dTOAttachFile.setOldAttachFileName(fileName);
					dTOAttachFile.setNewAttachFileName(getAttachRelativePath()+"/"+uid+"/"+fileName);
					list.add(dTOAttachFile);
					saveFileToFtp(fileName, mPart.getInputStream(),uid);
				} else if (mPart.isMimeType("multipart/*")) {
					saveAttachMent(mPart, messageId,attachFileMap,uid);
				} else {
					fileName = mPart.getFileName();
					if ((fileName != null)
							&& (fileName.toLowerCase().indexOf("GB2312") != -1)) {
						fileName = MimeUtility.decodeText(fileName);
						List<DTOAttachFile> list = attachFileMap.get(messageId);
						DTOAttachFile  dTOAttachFile = new DTOAttachFile();
						dTOAttachFile.setOldAttachFileName(fileName);
//						String extensionFileName = getExtensionName(fileName);
//						dTOAttachFile.setNewAttachFileName(getAttachRelativePath()+"/"+getRandomFileName()+"."+extensionFileName);
						dTOAttachFile.setNewAttachFileName(getAttachRelativePath()+"/"+uid+"/"+fileName);
						list.add(dTOAttachFile);
						saveFileToFtp(fileName, mPart.getInputStream(),uid);
					}
				}
			}
		} else if (part.isMimeType("message/rfc822")) {
			saveAttachMent((Part) part.getContent(),messageId,attachFileMap,uid);
		}
	}

	/**
	 * 　*　真正的保存附件到指定目录里 　
	 */
	private void saveFile(String fileName, InputStream in) throws Exception {
		String osName = System.getProperty("os.name");
		String storeDir = getAttachPath();
		String separator = "";
		if (osName == null) {
			osName = "";
		}
		if (osName.toLowerCase().indexOf("win") != -1) {
			separator = "\\";
			if (storeDir == null || storeDir.equals(""))
				storeDir = "c:\\tmp";
		} else {
			separator = "/";
			storeDir = "/tmp";
		}
		File storeFile = new File(storeDir + separator + fileName);
		//System.out.println("附件的保存地址:　" + storeFile.toString());
		// for(int　i=0;storefile.exists();i++){
		// storefile　=　new　File(storedir+separator+fileName+i);
		// }
		BufferedOutputStream bos = null;
		BufferedInputStream bis = null;

		try {
			bos = new BufferedOutputStream(new FileOutputStream(storeFile));
			bis = new BufferedInputStream(in);
			int c;
			while ((c = bis.read()) != -1) {
				bos.write(c);
				bos.flush();
			}
		} catch (Exception exception) {
			exception.printStackTrace();
			throw new Exception("文件保存失败!");
		} finally {
			bos.close();
			bis.close();
		}
	}
	
	/**
	 * 　*　真正的保存附件到指定目录里 　
	 */
	private void saveFileToFtp(String fileName, InputStream in,String uid) throws Exception {
		try {
			FTPClientUtil.uploadToRemote(saveAttachPath+"/"+uid, fileName, in);
		} catch (Exception exception) {
			exception.printStackTrace();
			throw new Exception("文件保存失败!");
		}
	}
	
	/**
	 * @param htmlStr
	 * @return 删除Html标签
	 */
	public static String delHTMLTag(String htmlStr) {
		Pattern p_script = Pattern.compile(regEx_script,
				Pattern.CASE_INSENSITIVE);
		Matcher m_script = p_script.matcher(htmlStr);
		htmlStr = m_script.replaceAll(""); // 过滤script标签

		Pattern p_style = Pattern
				.compile(regEx_style, Pattern.CASE_INSENSITIVE);
		Matcher m_style = p_style.matcher(htmlStr);
		htmlStr = m_style.replaceAll(""); // 过滤style标签

		Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
		Matcher m_html = p_html.matcher(htmlStr);
		htmlStr = m_html.replaceAll(""); // 过滤html标签

		Pattern p_space = Pattern
				.compile(regEx_space, Pattern.CASE_INSENSITIVE);
		Matcher m_space = p_space.matcher(htmlStr);
		htmlStr = m_space.replaceAll(""); // 过滤空格回车标签
		return htmlStr.trim(); // 返回文本字符串
	}

	public String getTextFromHtml(String htmlStr) {
		htmlStr = delHTMLTag(htmlStr);
		htmlStr = htmlStr.replaceAll("&nbsp;", "");
		return htmlStr;
	}
	
	
	 public static String getRandomFileName() {  
        SimpleDateFormat simpleDateFormat;  
  
        simpleDateFormat = new SimpleDateFormat("yyyyMMdd");  
  
        Date date = new Date();  
  
        String str = simpleDateFormat.format(date);  
  
        Random random = new Random();  
  
        int rannum = (int) (random.nextDouble() * (99999 - 10000 + 1)) + 10000;// 获取5位随机数  
  
        return rannum + str;// 当前时间  
	 }  
	
	 public static String getExtensionName(String filename) {   
	        if ((filename != null) && (filename.length() > 0)) {   
	            int dot = filename.lastIndexOf('.');   
	            if ((dot >-1) && (dot < (filename.length() - 1))) {   
	                return filename.substring(dot + 1);   
	            }   
	        }   
	        return filename;   
	 }   
	/**
	 * 　设置附件存放路径
	 */
	public void setAttachPath(String attachPath) {
		this.saveAttachPath = attachPath;
	}

	/**
	 * 　*　设置日期显示格式 　
	 */
	public void setDateFormat(String format) throws Exception {
		this.dateFormat = format;
	}

	/**
	 * 　*　获得附件存放路径 　
	 */
	public String getAttachPath() {
		return saveAttachPath;
	}
	
	
	
	
	public String getAttachRelativePath() {
		return attachRelativePath;
	}

	public void setAttachRelativePath(String attachRelativePath) {
		this.attachRelativePath = attachRelativePath;
	}

	public static void main(String[] args) throws Exception {
		System.out.println(System.getProperty("os.name"));
		 	/*String host = "pop.163.com";
	        String username = "zhangtaodeveloper@163.com";
	        String password = "zhangtao123";
	 */
//	        String host = "119.6.9.99";
//	        String username = "gzmx@chengduair.cc";
//	        String password = "cdhk1234";
//	        
//	        Properties props = new Properties();
//	        Session session = Session.getDefaultInstance(props, null);
//	 
//	        Store store = session.getStore("pop3");
//	        store.connect(host, username, password);
//	 
//	        Folder folder = store.getFolder("INBOX");
//	        folder.open(Folder.READ_ONLY);
//	        Message message[] = folder.getMessages();
//	        System.out.println("邮件数量:　" + message.length);
//	        MailParsingUtil re = null;
//	        
//	        
//	        
//	        
//	        if (folder instanceof POP3Folder) {
//	        	
//	        	POP3Folder inbox = (POP3Folder) folder;
//	        	
//				SearchTerm comparisonTermGe = new SentDateTerm(ComparisonTerm.GE, DateUtils.addDate(new Date(), -10));
//				SearchTerm comparisonTermLe = new SentDateTerm(ComparisonTerm.LE, new Date());
//				FromStringTerm fromStringTerm = new FromStringTerm("912340449@qq.com");
//				//SentDateTerm sentDateTerm = new SentDateTerm("", "");
//				
//				AndTerm andTerm = new AndTerm(comparisonTermGe, comparisonTermLe); 
//				//Message[] search = inbox.search(andTerm);
//		        //System.out.println("lalal:"+search.length);
//	        	
//	        	
//	        	
//	        	
//	        	
//				
//				Message[] messages = inbox.getMessages();
//				for (int i = 0; i < messages.length; i++) {
//					
//					System.out.println(messages[i].getSize());
//					
//					MimeMessage mimeMessage = (MimeMessage) messages[i];
//					
//					/************************获取UID*************************/
//					String uid = inbox.getUID(mimeMessage);
//					re = new MailParsingUtil((MimeMessage) message[i]);
//					System.out.println("UID:"+uid);
//					
//					/************************保存EML*************************/
//					File file = new File("D:\\FTP-应用程序发布\\Files\\Eml\\"+uid+"----"+i+".eml");
//					OutputStream os = new FileOutputStream(file);
//					message[i].writeTo(os);
//					InputStream in = new FileInputStream(file);
//					MimeMessage mm = new MimeMessage(session, in);
//					
//					
//					//System.out.println("~~~~~~~~~~~~~~~~~~~~~"+mm.getSubject());
//					
//		            System.out.println("邮件　" + i + "　主题:　" + re.getSubject());
//		            
//		            String subject = new String(re.getSubject().getBytes("UTF-8"));
//		            
//		            System.out.println("转码后的主题:"+subject);
//		            
//		            //String[] header = message[i].getHeader("From");
//		            System.out.println(re.getSentDate().toString().replace("-","").substring(0,6));;
//		    		//SimpleDateFormat format = new SimpleDateFormat(dateFormat);
//		    		//String strSentDate = format.format(sentDate);
//		            //System.out.println("邮件　" + i + "　发送时间:　" + sentDate);
//		            //System.out.println("邮件　" + i + "　是否需要回复:　" + re.getReplySign());
//		            /*System.out.println("邮件　" + i + "　是否已读:　" + re.isNew());
//		            System.out.println("邮件　" + i + "　是否包含附件:　"+ re.isContainAttach((Part) message[i]));
//		            System.out.println("邮件　" + i + "　发送人地址:　" + re.getFrom());
//		            System.out.println("邮件　" + i + "　收信人地址:　" + re.getMailAddress("to"));
//		            System.out.println("邮件　" + i + "　抄送:　" + re.getMailAddress("cc"));
//		            System.out.println("邮件　" + i + "　暗抄:　" + re.getMailAddress("bcc"));
//		            re.setDateFormat("yy年MM月dd日　HH:mm");
//		            System.out.println("邮件　" + i + "　发送时间:　" + re.getSentDate());
//		            System.out.println("邮件　" + i + "　邮件ID:　" + re.getMessageId());
//		            re.getMailContent((Part) message[i]);
//		            System.out.println("邮件　" + i + "　正文内容:　\r\n" + re.getBodyText());*/
//		            //re.setAttachPath("E:\\FileMail");
//		            //re.saveAttachMent((Part) message[i]);
//				}
//			}
	}
	
	
}